// /////////////////////////////////////////////////////////////////////////////
//
// Name:            ColourAnalyser.h
// Author:          Michael Bartsch
//
// Desc :           The interface for the CColourAnalyser class.
//
// License:         Copyright (C) 2008-2009 Michael Bartsch
//
//                  This program is free software: you can redistribute it
//                  and/or modify it under the terms of the GNU General Public
//                  License as published by the Free Software Foundation,
//                  either version 3 of the License, or (at your option) any
//                  later version.
//
//                  This program is distributed in the hope that it will be
//                  useful, but WITHOUT ANY WARRANTY; without even the implied
//                  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
//                  PURPOSE. See the GNU General Public License for more
//                  details.
//
//                  You should have received a copy of the GNU General Public
//                  License along with this program. If not, see
//                  <http://www.gnu.org/licenses/>.
//
// /////////////////////////////////////////////////////////////////////////////

#ifndef __C_COLOURANALYSER_H_INCLUDED__
#define __C_COLOURANALYSER_H_INCLUDED__

// Include required header file(s).
#include "../App/App.h"

#ifdef __OS_WINDOWS__
#include "../escapi-2.1/escapi.h"
#endif


// Forward Declarations.
class CColourAnalyser;


// The CColourAnalyser class.
//! Class that analyses the latest image taken by the webcam.
//!
//! @note A singleton metatable with the same functionalities as the
//! CColourAnalyser class can be accessed through the Lua Scripting
//! language. The functions of this metatable can be accessed with
//! ColourAnalyser:<function> (notice the colon!). If the end-user
//! does not wish to use the ColourAnalyser metatable in Lua he/she
//! can decide to use ca<function>.
//!
//! @see ColourScript.cpp ColourScript.h
class CColourAnalyser
{
public:

    //! Constructor
    CColourAnalyser();
    //! Deconstructor
    ~CColourAnalyser();

    //! Returns an instance of the singleton of CColourAnalyser.
    static CColourAnalyser* Instance();

    //! Gets the latest image from the webcam.
    //! @see lua_ca_updateImage
    void updateImage();
    //! Analyses the image that is currently loaded into the Colour Analyser.
    //!
    //! During the colour analysis the three RGB histograms will be created.
    //! Besides that the Colour Analyser will check if there is a match with
    //! the given values.
    //!
    //! @see lua_ca_analyseImage
    void analyseImage();

	//! Reconnects with the selected camera.
	//! @param ID the ID of the device
	void connect(int ID);

    // Get functions.
    //! Retrieves the currently loaded image in wxImage format.
    wxImage *getCameraImage();
    //! Retrieves the currently loaded image in wxBitmap format.
    wxBitmap *getCameraBitmap();

    //! Gets the latest histogram of the R(ed) analysis.
    wxBitmap *getHistogramR();
    //! Gets the latest histogram of the G(reen) analysis.
    wxBitmap *getHistogramG();
    //! Gets the latest histogram of the B(lue) analysis.
    wxBitmap *getHistogramB();

    //! Does the agent have a target?
    //! @see lua_ca_getIsTarget
    bool getIsTarget();
    //! Is there a match with the given RGB target?
    //! @see lua_ca_getIsMatchRGB
    bool getIsMatchRGB();
    //! Is there a match with the given R(ed) target?
    //! @see lua_ca_getIsMatchR
    bool getIsMatchR();
    //! Is there a match with the given G(reen) target?
    //! @see lua_ca_getIsMatchG
    bool getIsMatchG();
    //! Is there a match with the given B(lue) target?
    //! @see lua_ca_getIsMatchB
    bool getIsMatchB();

    //! Returns the target value for the R(ed) target.
    //! @see lua_ca_getTargetR
    int getTargetR();
    //! Returns the target value for the G(reen) target.
    //! @see lua_ca_getTargetG
    int getTargetG();
    //! Returns the target value for the B(lue) target.
    //! @see lua_ca_getTargetB
    int getTargetB();

    //! Returns the margin for the colour analysis.
    //! @see lua_ca_getTargetMargin
    int getTargetMargin();
    //! Returns the border for the colour analysis.
    //! @see lua_ca_getTargetBorder
    int getTargetBorder();

    //! Returns the biggest R(ed) value seen by the colour analyser.
    //! @see lua_ca_getBiggestR
    int getBiggestR();

    //! Returns the biggest G(reen) value seen by the colour analyser.
    //! @see lua_ca_getBiggestG
    int getBiggestG();

    //! Returns the biggest B(lue) value seen by the colour analyser.
    //! @see lua_ca_getBiggestB
    int getBiggestB();

    //! Returns the currently selected device.
    //! @see lua_ca_getSelectedDevice
    int getSelectedDevice();
	//! Returns the number of available devices.
	//! @see lua_ca_getDevices()
	int getDevices();

    // Set functions.
    //! Activate the given target.
    //! @param value activation state
    //! @see lua_ca_setIsTarget
    void setIsTarget(bool value);
    //! Sets the value of the R(ed) target.
    //! @param value colour value between 0 and 255
    //! @see lua_ca_setTargetR
    void setTargetR(int value);
    //! Sets the value of the G(reen) target.
    //! @param value colour value between 0 and 255
    //! @see lua_ca_setTargetG
    void setTargetG(int value);
    //! Sets the value of the B(lue) target.
    //! @param value colour value between 0 and 255
    //! @see lua_ca_setTargetB
    void setTargetB(int value);

    //! Sets the margin of the colour analysis.
    //! This margin specifies how much the main detected colour
    //! may deviate from the set colours.
    //!
    //! @param value colour value between 0 and 127
    //! @see lua_ca_setTargetMargin
    void setTargetMargin(int value);
    //! Sets the border for the colour analysis.
    //! This border specifies how much entries there should be
    //! of a certain colour before a positive match is given.
    //!
    //! @param value colour value between 0 and 101376
    //! @see lua_ca_setTargetBorder
    void setTargetBorder(int value);


private:

    // CColourAnalyser singleton.
	static CColourAnalyser *pInstance;

#ifdef __OS_WINDOWS__
	// ESCAPI objects.
	SimpleCapParams captureDevice;
	int devices;
	int selectedDevice;
	bool isConnected;
#endif

	// wxWidgets objects.
	wxImage *cameraImage;
	wxBitmap *cameraBitmap;

	wxImage *imageR, *imageG, *imageB;
	wxBitmap *histogramR, *histogramG, *histogramB;

	// Analysis objects.
	int countR[256], countG[256], countB[256];

	float biggestValueR, biggestValueG, biggestValueB;
	char biggestCountR, biggestCountG, biggestCountB;

	bool isTargetColour;
	bool isMatchRGB, isMatchR, isMatchG, isMatchB;

	char targetR, targetG, targetB;
	int targetCountR, targetCountG, targetCountB;
	int targetMargin, targetBorder;
};

#endif
